package com.dxy.app.widget.flexible_view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.support.annotation.Nullable;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import com.dxy.app.R;
import java.util.ArrayList;
import java.util.List;

/**
 * 描 叙: 隐藏显示多余内容的TextView
 * 作 者: duxingyu
 * 时 间: 2017/9/8 16:13
 **/

public class FlexibleTextView extends View {

  public static final String TAG="TAG_FlexibleTextView";
  /**
   * 绘制的文字内容
   * */
  private String text;
  /**
   * 字体颜色
   * */
  private int textColor;
  /**
   * 字体尺寸
   * */
  private float textSize;
  /**
   * 画笔
   * */
  private TextPaint paint;
  /**
   * 每行文字的高度
   * */
  private float lineHeight;
  /**
   * 可绘制区域的宽度
   * */
  private float drawTextWidth;
  /**
   * 开始绘制的x坐标和y轴坐标
   * */
  private float startX,startY;
  /**
   * 每行之间的间距
   * */
  private float textLineSpace;
  /**
   * 文字列表
   * */
  private List<String> textList;
  /**
   * 所有内容显示完需要的行数
   * */
  private int totalTextLineCount;
  /**
   * 是否显示全部内容，默认不是
   * */
  private boolean isShowAll =false;
  /**
   * 当处于隐藏多余内容的状态下的最小显示条数内容,取最小的值作为显示行数
   * */
  private int minCountWhileInHiden;
  /**
   * 隐藏时需要显示的文本行数
   * */
  private int maxLineCountWhileHiden;
  /**
   * 测量text时绘制文字起始基线高度，绘制时要用计算的高度减去这个值，得到的效果才能正确显示
   * */
  private float textOffsetY2MiddleLine;

  public FlexibleTextView(Context context) {
    super(context);
    init(null);
  }

  public FlexibleTextView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    TypedArray array =context.obtainStyledAttributes(attrs, R.styleable.FlexibleTextView);
    init(array);
  }

  public FlexibleTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    TypedArray array =context.obtainStyledAttributes(attrs, R.styleable.FlexibleTextView);
    init(array);
  }

  private void init(TypedArray array){
    float density =getResources().getDisplayMetrics().density;
    float scalce =getResources().getDisplayMetrics().scaledDensity;
    if(array!=null){
      textLineSpace =array.getDimensionPixelOffset(R.styleable.FlexibleTextView_flexible_line_space, (int) (5*density));
      maxLineCountWhileHiden =array.getInt(R.styleable.FlexibleTextView_flexible_max_line_in_hiden,3);
      textColor =array.getColor(R.styleable.FlexibleTextView_flexible_text_color,Color.BLACK);
      textSize =array.getDimensionPixelSize(R.styleable.FlexibleTextView_flexible_text_size, 40);
      array.recycle();
    }else{
      textSize =15*scalce;
      maxLineCountWhileHiden =3;
      textColor = Color.BLACK;
      textLineSpace =5*density;
    }
    paint =new TextPaint();
    paint.setAntiAlias(true);
    paint.setTextSize(textSize);
    paint.setColor(textColor);

    textList =new ArrayList<>();
  }

  @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    startX =getPaddingLeft();
    startY =getPaddingTop();
    drawTextWidth =w -getPaddingLeft()-getPaddingRight();
    initTextList();
  }

  public void setText(String text){
    if(TextUtils.isEmpty(text)){
      return;
    }
    this.text =text;
    initTextList();
  }
  /**
   * 初始化文字列表
   * */
  private void initTextList(){
    if(drawTextWidth==0){
      return;
    }
    if(TextUtils.isEmpty(text)){
      totalTextLineCount =0;
      return;
    }
    textList.clear();

    float totalTextWidth =paint.measureText(text);

    lineHeight =paint.descent() -paint.ascent();
    textOffsetY2MiddleLine =paint.descent();
    totalTextLineCount = (int) Math.ceil(totalTextWidth/drawTextWidth);
    if(totalTextLineCount*drawTextWidth<totalTextLineCount&&totalTextLineCount<drawTextWidth*(totalTextLineCount+1)){
      totalTextLineCount ++;
    }
    String textTemp =text;

    //以所有字符均为同一类型来计算每行显示字符的个数,这只是一个期望值而已
    int expectLineCharCount = text.length()/ totalTextLineCount;
    int lastLineEndCharIndex =0;//上一行最后一个字符的索引值

    for(int i=0;i<totalTextLineCount;i++){
      String temp;
      if(i==totalTextLineCount-1){//当达到最后一行时
        temp =textTemp.substring(lastLineEndCharIndex,textTemp.length());
      }else{
        int curLineEndCharIndex =lastLineEndCharIndex+expectLineCharCount;//当前行最后一个字符的位置,是基于上已行文字的最后位置
        float actualWidth =paint.measureText(textTemp,lastLineEndCharIndex,curLineEndCharIndex);//根据期望值测量出来的实际长度
        if(actualWidth>drawTextWidth){
          do{
            if(actualWidth<=drawTextWidth){
              break;
            }
            curLineEndCharIndex --;
            actualWidth =paint.measureText(textTemp,lastLineEndCharIndex,curLineEndCharIndex);
          }while(actualWidth>drawTextWidth);
        }else{
          do{
            if(actualWidth>drawTextWidth){
              curLineEndCharIndex --;//当测试的长度超过绘制宽度后，需要回退一个字符
              break;
            }
            curLineEndCharIndex ++;
            actualWidth =paint.measureText(textTemp,lastLineEndCharIndex,curLineEndCharIndex);
          }while (actualWidth>drawTextWidth);
        }
        temp =textTemp.substring(lastLineEndCharIndex,curLineEndCharIndex);
        lastLineEndCharIndex =curLineEndCharIndex;//将当前行的最后一个字符索引赋值为当前的最后一行的最后一个字符
      }
      textList.add(temp);
    }
    minCountWhileInHiden =maxLineCountWhileHiden>textList.size()?textList.size():maxLineCountWhileHiden;
    resetSize();
  }

  @Override protected void onDraw(Canvas canvas) {
    float temp =startY;
    if(isShowAll){
      for(String each:textList){
        temp =drawText(canvas,temp,each);
      }
    }else{
      for (int i = 0; i < minCountWhileInHiden; i++) {
        String each =textList.get(i);
        temp =drawText(canvas,temp,each);
      }
    }
  }
  /**
   * 绘制文字
   * @param canvas
   * @param text
   * @param y
   * */
  private float drawText(Canvas canvas,float y,String text){
    y+=lineHeight+textLineSpace;
    canvas.drawText(text,startX,y-textOffsetY2MiddleLine,paint);
    return y;
  }
  /**
   * 重新设置高度
   * */
  private void resetSize(){
    float totalHeight;
    if(isShowAll){
      totalHeight =lineHeight*totalTextLineCount+getPaddingBottom()+textLineSpace*totalTextLineCount+getPaddingTop();
    }else{
      totalHeight =lineHeight* minCountWhileInHiden +getPaddingBottom()+textLineSpace*(minCountWhileInHiden-1)+getPaddingTop();
    }
    getLayoutParams().height = (int) totalHeight;
    requestLayout();
    if(listener!=null){
      listener.afterRest(getIsShown(),isShowAll);
    }
  }

  /**
   * 获取当前是否需要显示显示更多的控件
   * */
  public boolean getIsShown(){
    return totalTextLineCount> maxLineCountWhileHiden;
  }
  /**
   * 切换显示状态
   * */
  public void switchState(){
    this.isShowAll =!isShowAll;
    resetSize();
  }
  /**
   * 获取当前的内容
   * */
  public String getText(){
    return text;
  }

  /**
   * 当完成对内容的分组后，通知界面显示相应元素的监听器
   * */
  private NotifyPageRefreshListener listener;

  public void setListener(NotifyPageRefreshListener listener){
    this.listener =listener;
  }
  public interface NotifyPageRefreshListener{
    /**
     * 当前状态改变
     * @param isNeedShowMore 通过计算后是否需要显示"展开"按钮
     * @param isShowAll 是否显示全部内容
     * */
    void afterRest(boolean isNeedShowMore,boolean isShowAll);
  }
}
